package com.patch;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 增量补丁打包工具
 * @author csshui
 *
 */
public class patchUtil {

	/**工作区路径**/
	private static String workSpaceRoute = "D:/workspace/for_365jzkt";
	/**补丁生成路径**/
	private static String patchGenRoute = "E:/mrjy_patch/patch/patch-by javin";
	/**补丁日志生成路径**/
	private static String patchLogGenRoute = "E:/mrjy_patch/patch/patch-by javin";
	/**补丁配置文件生成路径**/
	private static String patchConfigGenRoute = "E:/mrjy_patch/patch/patch-by javin";
	/**修改日志读取路径**/
	private static String changeLogRoute = "E:/mrjy_patch/patch/changeLog.txt";
	/**补丁路径过滤 通过该条件从修改日志过滤出补丁**/
	private static String Stringfilter = "/mrjy";
	/**过滤相应的文件（不生成相应的补丁）**/
	private static String fileFilter = "";
	/**版本号**/
	private static String version = "";	//为空时自动以时间为版本号
	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		if("".equals(version)){
		    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd.HHmmss");
	    	Date date = new Date();
			version = dateFormat.format(date);
		}
		patchGenRoute = patchConfigGenRoute + version + "/补丁";
		patchLogGenRoute = patchConfigGenRoute + version + "/补丁日志";
		patchConfigGenRoute = patchConfigGenRoute + version + "/配置文件";
		
		// TODO Auto-generated method stub
		 deleteDir(new File(patchGenRoute));		//删除旧补丁
		 deleteDir(new File(patchLogGenRoute));		//删除旧补丁日志
		 deleteDir(new File(patchConfigGenRoute));		//删除旧补丁配置
		 
		 File LogFile = new File(getChangeLogRoute());
		 new File(patchConfigGenRoute).mkdirs();
		 BufferedReader changeLog = new BufferedReader(new FileReader(LogFile));
		 String readLine = null;
		 String projectName = null;	//项目名称
		 String patchRoute = null;	//补丁路径
		 String patchName = null;	//补丁名称
		 int n = 0;
		 //补丁路径
		 File patch = new File(patchLogGenRoute);
		 if(!patch.exists()){
			patch.mkdirs();
		 }
		 File patchLog = new File(patchLogGenRoute + "/修改日志.txt"); 
		 BufferedWriter patchLogOutput = new BufferedWriter(new FileWriter(patchLog));
		 //初始化日志模版
		 patchLogOutput.write("解决问题:" + "\n 1 \n");
		 patchLogOutput.write("---------------------------" + "\n");
		 patchLogOutput.write("备注:(请于下方填写jar包更新到哪些工程)" + "\n 1 \n");
		 patchLogOutput.write("---------------------------" + "\n");
		 patchLogOutput.write("相应更新文件:" + "\n");
		 try{
			 while ((readLine = changeLog.readLine()) != null) {
				if(readLine.indexOf(".classpath")>0 || readLine.indexOf(".setting")>0 )
					continue;
				if(readLine.indexOf(Stringfilter)== -1)
					continue;
				//readLine = readLine.substring(readLine.indexOf(Stringfilter)+Stringfilter.length());
				readLine = readLine.substring(readLine.indexOf(Stringfilter));
				readLine = readLine.replace(".java", ".class");
				
				/*String routeDir = "";
				routeDir = readLine.split("/")[1].toString();
				//String routeDir = readLine.split("/")[1].toString();
				readLine = readLine.replace("/" + routeDir + "/", "/");*/
				
				//patchLogOutput.write(readLine + "\n");
				projectName = readLine.split("/")[1].toString();
				patchRoute = readLine.substring(readLine.indexOf(projectName) + projectName.length() + 1);
				if (readLine.indexOf("src/") > -1) {
					patchRoute = readLine.substring(readLine.indexOf("src/") + "src/".length());
				}
				patchName = readLine.split("/")[readLine.split("/").length - 1].toString();
				if(!fileFilter.isEmpty() && patchName.indexOf(fileFilter)!= -1){
					continue;
				}
				String outputRoute = null;
				String patchSrcRoute = null;
				String patchDesRoute = null;
				if (patchName.indexOf(".class") > 0 || patchName.indexOf(".xml") > 0 || patchName.indexOf(".properties") > 0) {
					BufferedReader classpath = new BufferedReader(new FileReader(workSpaceRoute + "/" + projectName + "/.classpath"));
					while ((outputRoute = classpath.readLine()) != null) {
						if(outputRoute.indexOf("classpathentry kind=\"output\"") > 0){
							patchSrcRoute = workSpaceRoute + "/" + projectName + "/" + outputRoute.split("\"")[3].toString()
									+ "/" + patchRoute;
							/*//判断是web工程还是普通的jar包
							if(new File(workSpaceRoute + "/" + projectName + "/WebContent/WEB-INF/web.xml").exists()
									&& patchName.indexOf(".class") > 0){
								patchDesRoute = patchGenRoute + "/" + projectName + "/WEB-INF/classes/" + patchRoute;
							}else{
								patchDesRoute = patchGenRoute + "/" + projectName + "/" + patchRoute;
							}*/
							if (patchName.indexOf(".class") > 0 || patchName.indexOf(".xml") > 0 
									|| patchName.indexOf(".properties") > 0 || patchName.indexOf(".jsp") > 0 ) {
								patchDesRoute = patchGenRoute + "/" + projectName + "/WEB-INF/classes/" + patchRoute;
							}else{
								//patchDesRoute = patchGenRoute + "/" + projectName + "/" + patchRoute;
							}
							
							
							CopyFile(patchSrcRoute,patchDesRoute);
							++n;
							//捞取Java文件里还有别的【内部类、【非公有类】等 带$号的class文件
							if(patchName.indexOf(".class") > 0)
							{
								for(int n1 = 1; n1 < 100; n1++){
									if(new File(patchSrcRoute.replace(".class", "$" + n1 + ".class")).exists()){
										CopyFile(patchSrcRoute.replace(".class", "$" + n1 + ".class"),
												 patchDesRoute.replace(".class", "$" + n1 + ".class"));

										++n;
									}else{
										break;
									}
										
								}
							}
							break;
						}
							 
					}
				}else if(patchName.indexOf(".html") > 0 || patchName.indexOf(".js") > 0 || patchName.indexOf(".jsp") > 0 ||  patchName.indexOf(".jar") > 0) {
					patchSrcRoute = workSpaceRoute + "/" + projectName + "/" + patchRoute;
					if (patchRoute.indexOf("WebContent/") > -1) {
						patchRoute = patchRoute.substring(patchRoute.indexOf("WebContent/") + "WebContent/".length());
					}
					patchDesRoute = patchGenRoute  + "/" + projectName + "/" + patchRoute;
					CopyFile(patchSrcRoute,patchDesRoute);
					++n;
				}
				if(patchDesRoute != null){
					//tomcat 的项目路径
					patchDesRoute = patchDesRoute.substring(patchRoute.indexOf(patchGenRoute) + patchGenRoute.length()+1);
					patchLogOutput.write(patchDesRoute + "\n");
				}
				
			}
			System.out.print("patch generate success, count:" + n);
		}catch (Exception e) {
			// TODO: handle exception
			System.out.print("patch generate faild");
			e.printStackTrace();
		}finally{
			patchLogOutput.flush();
		}
	}
	
	public static Boolean CopyFile(String srcRoute,String desRoute){
		try{
			FileInputStream input=new FileInputStream(srcRoute); //读取源文件
			String fileName = desRoute.split("/")[desRoute.split("/").length - 1].toString();
			File patchPath = new File(desRoute.substring(0,desRoute.indexOf(fileName)));
			if(!patchPath.exists()){
				patchPath.mkdirs();
			}
			FileOutputStream output=new FileOutputStream(desRoute);	//生成目标文件
			int in=input.read();
			while(in!=-1){
				output.write(in);
				in=input.read();
			}
			input.close();
			output.flush();
		}catch (IOException e){
			System.out.println(e.toString());
		}
		return null; 
	} 

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     */
    private static boolean deleteDir(File dir) {
    	if(!dir.exists())
    		return true;
        if (dir.isDirectory()) {
            String[] children = dir.list();
            //递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }
	public static String getWorkSpaceRoute() {
		return workSpaceRoute;
	}
	public static void setWorkSpaceRoute(String workSpaceRoute) {
		patchUtil.workSpaceRoute = workSpaceRoute;
	}
	public static String getpatchGenRoute() {
		return patchGenRoute;
	}
	public static void setpatchGenRoute(String patchGenRoute) {
		patchUtil.patchGenRoute = patchGenRoute;
	}
	public static String getChangeLogRoute() {
		return changeLogRoute;
	}
	public static void setChangeLogRoute(String changeLogRoute) {
		patchUtil.changeLogRoute = changeLogRoute;
	}

	public static String getPatchGenRoute() {
		return patchGenRoute;
	}

	public static void setPatchGenRoute(String patchGenRoute) {
		patchUtil.patchGenRoute = patchGenRoute;
	}

	public static String getPatchLogGenRoute() {
		return patchLogGenRoute;
	}

	public static void setPatchLogGenRoute(String patchLogGenRoute) {
		patchUtil.patchLogGenRoute = patchLogGenRoute;
	}

	public static String getPatchConfigGenRoute() {
		return patchConfigGenRoute;
	}

	public static void setPatchConfigGenRoute(String patchConfigGenRoute) {
		patchUtil.patchConfigGenRoute = patchConfigGenRoute;
	}

	public static String getStringfilter() {
		return Stringfilter;
	}

	public static void setStringfilter(String stringfilter) {
		Stringfilter = stringfilter;
	}

	public static String getFileFilter() {
		return fileFilter;
	}

	public static void setFileFilter(String fileFilter) {
		patchUtil.fileFilter = fileFilter;
	}

	public static void setVersion(String version) {
		patchUtil.version = version;
	}

	public static String getVersion() {
		return version;
	}
	
}
